home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Programming / SWI / source / boot / list.pl < prev    next >
Encoding:
Text File  |  1997-12-03  |  4.8 KB  |  205 lines

  1. /*  $Id: list.pl,v 1.3 1997/12/03 08:51:41 jan Exp $
  2.  
  3.     Copyright (c) 1990 Jan Wielemaker. All rights reserved.
  4.     jan@swi.psy.uva.nl
  5.  
  6.     Purpose: basic list predicates
  7. */
  8.  
  9. :- module($list,
  10.     [ length/2
  11.     , select/3
  12.     , delete/3
  13.     , nth0/3
  14.     , nth1/3
  15.     , last/2
  16.     , reverse/2
  17.     , flatten/2
  18.     , is_set/1
  19.     , list_to_set/2
  20.     , intersection/3
  21.     , union/3
  22.     , subset/2
  23.     , subtract/3
  24.     ]).
  25.  
  26. %    length(?List, ?N)
  27. %    Is true when N is the length of List.
  28.  
  29. length(List, Length) :-
  30.     $length(List, Length), !.        % written in C
  31. length(List, Length) :-
  32.     var(Length),
  33.     length2(List, Length).
  34.  
  35. length2([], 0).
  36. length2([_|List], N) :-
  37.     length2(List, M), 
  38.     succ(M, N).
  39.  
  40. %    select(?List1, ?Elem, ?List2)
  41. %    Is true when List1, with Elem removed results in List2.
  42.  
  43. select([X|Tail], X, Tail).
  44. select([Head|Tail], Elem, [Head|Rest]) :-
  45.     select(Tail, Elem, Rest).
  46.  
  47. %    delete(?List1, ?Elem, ?List2)
  48. %    Is true when Lis1, with all occurences of Elem deleted results in
  49. %    List2.
  50.  
  51. delete([], _, []) :- !.
  52. delete([Elem|Tail], Elem, Result) :- !, 
  53.     delete(Tail, Elem, Result).
  54. delete([Head|Tail], Elem, [Head|Rest]) :-
  55.     delete(Tail, Elem, Rest).
  56.  
  57. /*  nth0/3, nth1/3 are improved versions from
  58.     Martin Jansche <martin@pc03.idf.uni-heidelberg.de>
  59. */
  60.  
  61. %%  nth0(?Index, ?List, ?Elem)
  62. %%  is true when Elem is the Index'th element of List.  Counting starts
  63. %%  at 0.  [This is a faster version of the original SWI-Prolog predicate.]
  64.  
  65. nth0(Index, List, Elem) :-
  66.         integer(Index), !,
  67.         Index >= 0,
  68.         nth0_det(Index, List, Elem).    %% take nth deterministically
  69. nth0(Index, List, Elem) :-
  70.         var(Index), !,
  71.         nth_gen(List, Elem, 0, Index).  %% match
  72.  
  73. nth0_det(0, [Elem|_], Elem) :- !.
  74. nth0_det(1, [_,Elem|_], Elem) :- !.
  75. nth0_det(2, [_,_,Elem|_], Elem) :- !.
  76. nth0_det(3, [_,_,_,Elem|_], Elem) :- !.
  77. nth0_det(4, [_,_,_,_,Elem|_], Elem) :- !.
  78. nth0_det(5, [_,_,_,_,_,Elem|_], Elem) :- !.
  79. nth0_det(N, [_,_,_,_,_,_   |Tail], Elem) :-
  80.         M is N - 6,
  81.         nth0_det(M, Tail, Elem).
  82.  
  83. nth_gen([Elem|_], Elem, Base, Base).
  84. nth_gen([_|Tail], Elem, N, Base) :-
  85.         succ(N, M),
  86.         nth_gen(Tail, Elem, M, Base).
  87.  
  88.  
  89. %%  nth1(?Index, ?List, ?Elem)
  90. %%  Is true when Elem is the Index'th element of List.  Counting starts
  91. %%  at 1.  [This is a faster version of the original SWI-Prolog predicate.]
  92.  
  93. nth1(Index1, List, Elem) :-
  94.         integer(Index1), !,
  95.         Index0 is Index1 - 1,
  96.         nth0_det(Index0, List, Elem).   %% take nth deterministically
  97. nth1(Index, List, Elem) :-
  98.         var(Index), !,
  99.         nth_gen(List, Elem, 1, Index).  %% match
  100.  
  101. %    last(?Elem, ?List)
  102. %    Succeeds if `Last' unifies with the last element of `List'.
  103.  
  104. last(Elem, [Elem]).
  105. last(Elem, [_|List]) :-
  106.     last(Elem, List).
  107.  
  108. %    reverse(?List1, ?List2)
  109. %    Is true when the elements of List2 are in reverse order compared to
  110. %    List1.
  111.  
  112. reverse(L1, L2) :-
  113.     $reverse(L1, [], L2).
  114.  
  115. $reverse([], List, List).
  116. $reverse([Head|List1], List2, List3) :-
  117.     $reverse(List1, [Head|List2], List3).
  118.  
  119. %    flatten(+List1, ?List2)
  120. %    Is true when Lis2 is a non nested version of List1.
  121.  
  122. flatten(List, FlatList) :-
  123.     $flatten(List, [], FlatList), !.
  124.  
  125. $flatten(Var, Tl, [Var|Tl]) :-
  126.     var(Var), !.
  127. $flatten([], Tl, Tl) :- !.
  128. $flatten([Hd|Tl], Tail, List) :-
  129.     $flatten(Hd, FlatHeadTail, List), 
  130.     $flatten(Tl, Tail, FlatHeadTail).
  131. $flatten(Atom, Tl, [Atom|Tl]).
  132.  
  133.  
  134.         /********************************
  135.         *       SET MANIPULATION        *
  136.         *********************************/
  137.  
  138. %    is_set(+Set)
  139. %    is True if Set is a proper list without duplicates.
  140.  
  141. is_set(0) :- !, fail.        % catch variables
  142. is_set([]) :- !.
  143. is_set([H|T]) :-
  144.     memberchk(H, T), !, 
  145.     fail.
  146. is_set([_|T]) :-
  147.     is_set(T).
  148.  
  149. %    list_to_set(+List, ?Set)
  150. %    is true when Set has the same element as List in the same order
  151.  
  152. list_to_set(List, Set) :-
  153.     list_to_set_(List, Set0),
  154.     Set = Set0.
  155.  
  156. list_to_set_([], R) :-
  157.     close_list(R).
  158. list_to_set_([H|T], R) :-
  159.     memberchk(H, R), !, 
  160.     list_to_set_(T, R).
  161.  
  162. close_list([]) :- !.
  163. close_list([_|T]) :-
  164.     close_list(T).
  165.  
  166. %    intersection(+Set1, +Set2, -Set3)
  167. %    Succeeds if Set3 unifies with the intersection of Set1 and Set2
  168.  
  169. intersection([], _, []) :- !.
  170. intersection([X|T], L, Intersect) :-
  171.     memberchk(X, L), !, 
  172.     Intersect = [X|R], 
  173.     intersection(T, L, R).
  174. intersection([_|T], L, R) :-
  175.     intersection(T, L, R).
  176.  
  177. %    union(+Set1, +Set2, -Set3)
  178. %    Succeeds if Set3 unifies with the union of Set1 and Set2
  179.  
  180. union([], L, L) :- !.
  181. union([H|T], L, R) :-
  182.     memberchk(H, L), !, 
  183.     union(T, L, R).
  184. union([H|T], L, [H|R]) :-
  185.     union(T, L, R).
  186.  
  187. %    subset(+SubSet, +Set)
  188. %    Succeeds if all elements of SubSet belong to Set as well.
  189.  
  190. subset([], _) :- !.
  191. subset([E|R], Set) :-
  192.     memberchk(E, Set), 
  193.     subset(R, Set).
  194.  
  195. %    subtract(+Set, +Delete, -Result)
  196. %    Delete all elements from `Set' that occur in `Delete' (a set) and
  197. %    unify the result with `Result'.
  198.  
  199. subtract([], _, []) :- !.
  200. subtract([E|T], D, R) :-
  201.     memberchk(E, D), !,
  202.     subtract(T, D, R).
  203. subtract([H|T], D, [H|R]) :-
  204.     subtract(T, D, R).
  205.